<template>
  <AxiomDialog
    :model-value="visible"
    :title="`为【${roleData?.role_name}】分配权限`"
    width="500px"
    @close="handleClose"
    @cancel="handleClose"
    @confirm="handleConfirm"
    :loading="treeLoading && !isTreeReady"
    :confirm-loading="confirmButtonLoading"
    :confirm-disabled="isSuperAdmin"
    confirm-button-text="更新"
  >
    <!-- [修复] 为超级管理员添加只读提示 -->
    <div v-if="isSuperAdmin" style="margin-bottom: 16px; color: var(--axiom-text-color-secondary); font-size: 14px;">
      超级管理员默认拥有所有权限，不允许修改。
    </div>
    <AxiomTree
      ref="treeRef"
      :data="permissionTree"
      :loading="treeLoading"
      show-checkbox
      node-key="id"
      :props="{ label: 'permission_name', children: 'children', disabled: 'disabled' }"
      :default-expand-all="true"
    />
  </AxiomDialog>
</template>

<script setup>
import { ref, watch, nextTick, inject, computed } from 'vue';
import { AxiomDialog, AxiomTree } from 'axiom-view';
import { getPermissionTree } from '@/api/system/permission';
import { assignPermissionsToRole, getRoleDetails } from '@/api/system/role';

const props = defineProps({
  visible: {
    type: Boolean,
    default: false,
  },
  roleData: {
    type: Object,
    default: () => null,
  },
});

const emit = defineEmits(['close', 'success']);
const { notification } = inject('axiom-utils');
const treeRef = ref(null);

const confirmButtonLoading = ref(false);
const treeLoading = ref(false);
const permissionTree = ref([]);
const checkedKeys = ref([]);
const isTreeReady = ref(false);

// [修复] 添加计算属性以识别超级管理员
const isSuperAdmin = computed(() => props.roleData?.role_name === '超级管理员');

// [修复] 递归函数，用于禁用树的所有节点
const processTreeNodes = (nodes, isDisabled) => {
  if (!nodes || !Array.isArray(nodes)) return [];
  return nodes.map(node => ({
    ...node,
    disabled: isDisabled,
    children: processTreeNodes(node.children, isDisabled),
  }));
};

watch(() => props.visible, async (val) => {
  if (val && props.roleData) {
    isTreeReady.value = false;
    await fetchData();
  }
});

const fetchData = async () => {
  treeLoading.value = true;
  permissionTree.value = [];
  checkedKeys.value = [];
  try {
    const treeRes = await getPermissionTree();
    const rawTree = (treeRes && treeRes.success) ? treeRes.data || [] : [];
    
    // [修复] 为超级管理员禁用所有节点
    permissionTree.value = processTreeNodes(rawTree, isSuperAdmin.value);
    
    await nextTick();

    if (isSuperAdmin.value) {
      // [修复] 如果是超级管理员，则默认全选所有权限
      const getAllIds = (nodes) => nodes.reduce((acc, node) => {
        acc.push(node.id);
        if (node.children) acc.push(...getAllIds(node.children));
        return acc;
      }, []);
      checkedKeys.value = getAllIds(permissionTree.value);
    } else {
      // 对其他角色，正常获取其权限
      const detailsRes = await getRoleDetails(props.roleData.id);
      const assignedPermissions = (detailsRes && detailsRes.success && detailsRes.data) ? (detailsRes.data.permissions || []) : [];

      if (assignedPermissions.length > 0) {
        const assignedIds = new Set(assignedPermissions.map(p => p.id));
        
        // [关键修复]
        // 我们只应该设置叶子节点的选中状态。树组件会自动计算父节点的“半选”状态。
        // 如果我们把父节点的 ID 也传给 setCheckedKeys，它会把该父节点下的所有子节点都选中，这是导致 bug 的原因。
        const leafKeysToSet = [];
        const findLeafKeys = (nodes) => {
          for (const node of nodes) {
            // 如果节点是叶子节点 (没有 children) 且其 ID 在已分配权限列表中，则添加到待选中列表
            if ((!node.children || node.children.length === 0) && assignedIds.has(node.id)) {
              leafKeysToSet.push(node.id);
            }
            // 无论当前节点是不是叶子节点，都需要继续遍历其子节点
            if (node.children && node.children.length > 0) {
              findLeafKeys(node.children);
            }
          }
        };

        findLeafKeys(permissionTree.value);
        checkedKeys.value = leafKeysToSet;
      } else {
        checkedKeys.value = [];
      }
    }

    if (treeRef.value) {
      // 仅用叶子节点的 key 来设置树的状态
      treeRef.value.setCheckedKeys(checkedKeys.value);
    }

    isTreeReady.value = true;
  } catch (error) {
    console.error('加载权限数据失败:', error);
    notification.error({ title: '错误', message: '加载权限数据失败' });
  } finally {
    treeLoading.value = false;
  }
};

const handleClose = () => {
  permissionTree.value = [];
  checkedKeys.value = [];
  isTreeReady.value = false;
  if (treeRef.value) {
    treeRef.value.setCheckedKeys([]);
  }
  emit('close');
};

const handleConfirm = async () => {
  // [修复] 禁止为超级管理员执行更新操作
  if (isSuperAdmin.value || !treeRef.value) {
    return;
  }

  confirmButtonLoading.value = true;
  try {
    const selectedKeys = treeRef.value.getCheckedKeys();
    const halfSelectedKeys = treeRef.value.getHalfCheckedKeys();
    const allKeys = [...selectedKeys, ...halfSelectedKeys];
    
    await assignPermissionsToRole(props.roleData.id, allKeys);
    notification.success({ title: '成功', message: '权限分配成功' });
    
    // [修复] 在 success 事件中携带更新后的数据，以便父组件能够高效地同步状态
    emit('success', { roleId: props.roleData.id, permissionKeys: allKeys });
    handleClose();
  } catch (error) {
    // 错误通知已由全局 apiClient 处理
    console.error('分配权限失败:', error);
  } finally {
    confirmButtonLoading.value = false;
  }
};
</script> 